<!--
 * @Descripttion: 代码编辑器
 * @version: 1.0
 * @Author: bllxmx
 * @Date: 2022年5月20日21:46:29
 * @LastEditors: 
 * @LastEditTime: 
-->

<template>
  <div ref="main"
       class="editor-container"
       id="editor"
       style="width: 100%;"
       :style="{'height':_height}"
  />
</template>

<script setup>
import {onMounted, onUnmounted, reactive, ref} from 'vue'
import * as monaco from 'monaco-editor'

import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'


// 在初始化之前，先设置MonacoEnvironment
self.MonacoEnvironment = {
  getWorker(_, label) {
    if (label === 'json') {
      return new jsonWorker()
    }
    if (label === 'css' || label === 'scss' || label === 'less') {
      return new cssWorker()
    }
    if (label === 'html' || label === 'handlebars' || label === 'razor') {
      return new htmlWorker()
    }
    if (label === 'typescript' || label === 'javascript') {
      return new tsWorker()
    }
    return new editorWorker()
  }
}

const main = ref()

let editor = reactive()
const props = defineProps({
  initValue: {
    type: String,
    default: '',
  },
  _height: {
    type: String,
    default: '200px',
  },
  language: {
    type: String,
    default: 'json',
  },
})

const defaultOptions = {
  value: props.initValue, // 默认显示的值
  language: props.language, // 语言
  folding: true, // 是否折叠
  minimap: {
    // 关闭小地图
    enabled: false,
  },
  wordWrap: 'on',
  wrappingIndent: 'indent',
  foldingHighlight: true, // 折叠等高线
  foldingStrategy: 'indentation', // 折叠方式  auto | indentation
  showFoldingControls: 'always', // 是否一直显示折叠 always | mouseover
  disableLayerHinting: true, // 等宽优化
  emptySelectionClipboard: false, // 空选择剪切板
  selectionClipboard: true, // 选择剪切板
  automaticLayout: true, // 自动布局
  overviewRulerBorder: false, // 不要滚动条的边框
  codeLens: true, // 代码镜头
  scrollBeyondLastLine: true, // 滚动完最后一行后再滚动一屏幕
  colorDecorators: true, // 颜色装饰器
  accessibilitySupport: 'on', // 辅助功能支持  "auto" | "off" | "on"
  lineNumbers: 'on', // 行号 取值： "on" | "off" | "relative" | "interval" | function
  lineNumbersMinChars: 5, // 行号最小字符   number
  enableSplitViewResizing: 'on', // 是否允许调整视图大小
  fixedOverflowWidgets: true,
  quickSuggestions: true,
  acceptSuggestionOnEnter: 'on', // 粘贴时是否使用回车键
  formatOnPaste: true, // 粘贴时自动格式化
  theme: 'vs-dark', // 编辑器主题 默认vs-dark VSCode 黑色主题,可选：vs、vs-dark、hc-black、hc-light
  readOnly: false, // 是否只读内容不可编辑
  readOnlyMessage: {value: "不可以修改哦", supportThemeIcons: true, supportHtml: true}, // 为只读时编辑内日提示词
  snippetSuggestions: 'inline', // 代码提示
  tabCompletion: 'on', // 代码提示按tab完成
  smoothScrolling: true, // 滚动动画
  inDiffEditor: true,// 是否在差异编辑器中使用
  ariaLabel: true, // 编辑器文本区域的无障碍标签
  ariaRequired: true,// 是否设置 aria-required 属性
  screenReaderAnnounceInlineSuggestion: true,//是否立即宣布内联建议内容
  // tabIndex: 编辑器文本区域的 tabindex 属性
  // rulers: 指定位置渲染垂直线
  // wordSegmenterLocales: 用于词分割的语言
  // wordSeparators: 词导航时使用的分隔符
  // selectionClipboard: 启用 Linux 主剪贴板
  // lineNumbers: 控制行号的显示方式
  // cursorSurroundingLines: 控制光标周围的可见行数
  // cursorSurroundingLinesStyle: 控制何时强制执行 cursorSurroundingLines
  // renderFinalNewline: 渲染文件末尾的新行
  // unusualLineTerminators: 移除不寻常的行终止符
  // selectOnLineNumbers: 单击行号时选择相应行
  // lineNumbersMinChars: 控制行号的最小字符数
  // glyphMargin: 启用渲染图符边距
  // lineDecorationsWidth: 行装饰的宽度
  // revealHorizontalRightPadding: 水平方向显示光标时的虚拟填充
  // roundedSelection: 选择是否带有圆角
  // extraEditorClassName: 添加到编辑器的类名
  // readOnlyMessage: 只读模式下的提示信息
  // domReadOnly: 输入文本框是否使用 DOM 的 readonly 属性
  // linkedEditing: 启用关联编辑
  // renderValidationDecorations: 是否渲染验证装饰
  // scrollbar: 控制滚动条的行为和渲染
  // stickyScroll: 控制粘性滚动选项
  // minimap: 控制最小地图的行为和渲染
  // find: 控制查找小部件的行为
  // fixedOverflowWidgets: 以 fixed 方式显示溢出小部件
  // overviewRulerLanes: 概览尺子应渲染的车道数
  // overviewRulerBorder: 是否绘制概览尺子边框
  // cursorBlinking: 光标闪烁风格
  // mouseWheelZoom: 使用鼠标滚轮结合 Ctrl 键缩放字体
  // mouseStyle: 鼠标指针样式
  // cursorSmoothCaretAnimation: 平滑光标动画
  // cursorStyle: 光标样式
  // cursorWidth: 光标宽度
  // fontLigatures: 启用字体连字
  // fontVariations: 启用字体变体
  // defaultColorDecorators: 是否使用默认颜色装饰
  // disableLayerHinting: 禁用编辑器层提示
  // disableMonospaceOptimizations: 禁用等宽字体优化
  // hideCursorInOverviewRuler: 是否在概览尺子中隐藏光标
  // scrollBeyondLastLine: 启用滚动到最后行
  // scrollBeyondLastColumn: 启用滚动到最后列
  // smoothScrolling: 启用平滑滚动
  // automaticLayout: 启用自动布局
  // wordWrap: 控制自动换行
  // wordWrapOverride1: 覆盖 wordWrap 设置
  // wordWrapOverride2: 覆盖 wordWrapOverride1 设置
  // wordWrapColumn: 换行列数
  // wrappingIndent: 控制换行的缩进
  // wrappingStrategy: 控制换行策略
  // wordWrapBreakBeforeCharacters: 换行前的字符
  // wordWrapBreakAfterCharacters: 换行后的字符
  // wordBreak: 控制单词换行
  // stopRenderingLineAfter: 停止渲染行的位置
  // hover: 配置编辑器的悬浮提示
  // links: 启用链接检测
  // colorDecorators: 启用内联颜色装饰
  // colorDecoratorsActivatedOn: 触发颜色选择器的条件
  // colorDecoratorsLimit: 内联颜色装饰的最大数量
  // comments: 控制编辑器中的注释行为
  // contextmenu: 启用自定义上下文菜单
  // mouseWheelScrollSensitivity: 鼠标滚轮滚动灵敏度
  // fastScrollSensitivity: 快速滚动速度
  // scrollPredominantAxis: 启用主要轴滚动
  // columnSelection: 启用列选择
  // multiCursorModifier: 添加多个光标的修饰键
  // multiCursorMergeOverlapping: 合并重叠的选择
  // multiCursorPaste: 配置粘贴多个文本时的行为
  // multiCursorLimit: 控制同时可以存在的最大文本光标数量
  // accessibilitySupport: 配置编辑器的无障碍支持
  // accessibilityPageSize: 屏幕阅读器可读取的行数
  // suggest: 建议选项
  // inlineSuggest: 内联建议选项
  // experimentalInlineEdit: 实验性内联编辑选项
  // smartSelect: 智能选择选项
  // gotoLocation: 跳转到位置选项
  // quickSuggestions: 启用快速建议
  // quickSuggestionsDelay: 快速建议显示延迟
  // padding: 控制编辑器的边距
  // parameterHints: 参数提示选项
  // autoClosingBrackets: 自动闭合括号的选项
  // autoClosingComments: 自动闭合注释的选项
  // autoClosingQuotes: 自动闭合引号的选项
  // autoClosingDelete: 自动闭合删除的选项
  // autoClosingOvertype: 自动闭合覆盖的选项
  // autoSurround: 自动环绕的选项
  // autoIndent: 控制自动缩进
  // stickyTabStops: 插入和删除空白时遵循制表符停止
  // formatOnType: 启用输入时格式化
  // formatOnPaste: 启用粘贴时格式化
  // dragAndDrop: 允许通过拖放移动选择
  // suggestOnTriggerCharacters: 在触发字符上弹出建议框
  // acceptSuggestionOnEnter: 在 Enter 键上接受建议的方式
  // acceptSuggestionOnCommitCharacter: 在提供者定义的字符上接受建议
  // snippetSuggestions: 启用片段建议
  // emptySelectionClipboard: 无选择时复制当前行
  // copyWithSyntaxHighlighting: 复制时包含语法高亮
  // suggestSelection: 建议的历史模式
  // suggestFontSize: 建议小部件的字体大小
  // suggestLineHeight: 建议小部件的行高
  // tabCompletion: 启用 Tab 完成
  // selectionHighlight: 启用选择高亮
  // occurrencesHighlight: 启用语义发生高亮
  // codeLens: 显示代码透镜
  // codeLensFontFamily: 代码透镜的字体系列
  // codeLensFontSize: 代码透镜的字体大小
  // lightbulb: 控制代码操作灯泡的行为
  // codeActionsOnSaveTimeout: 保存时运行代码操作的超时时间
  // folding: 启用代码折叠
  // foldingStrategy: 选择折叠策略
  // foldingHighlight: 启用折叠区域高亮
  // foldingImportsByDefault: 默认折叠导入区域
  // foldingMaximumRegions: 最大可折叠区域数
  // showFoldingControls: 折叠控制的显示方式
  // unfoldOnClickAfterEndOfLine: 单击折行后展开
  matchBrackets: true,// 启用匹配括号高亮
  // experimentalWhitespaceRendering: 实验性空白渲染
  // renderWhitespace: 渲染空白字符
  // renderControlCharacters: 渲染控制字符
  // renderLineHighlight: 渲染当前行高亮
  // renderLineHighlightOnlyWhenFocus: 仅当编辑器聚焦时渲染当前行高亮
  // useTabStops: 插入和删除空白时遵循制表符停止
  // fontFamily: 字体系列
  // fontWeight: 字体粗细
  // fontSize: 字体大小
  // lineHeight: 行高
  // letterSpacing: 字母间距
  // showUnused: 控制未使用变量的高亮
  // peekWidgetDefaultFocus: 默认聚焦预览窗口的小部件
  // placeholder: 编辑器为空时显示的占位符
  // definitionLinkOpensInPeek: 定义链接是否在预览窗口中打开
  // showDeprecated: 控制废弃变量的高亮
  // matchOnWordStartOnly: 是否允许单词中间匹配
  // inlayHints: 控制内联提示的行为和渲染
}


onMounted(() => {
  init()
})

onUnmounted(() => {
  editor.dispose()
})

function init() {
  editor = monaco.editor.create(
      document.getElementById('editor'),
      defaultOptions,
  )
}

const getValue = () => {
  return editor.getValue()
}

const setValue = (val) => {
  editor.setValue(val)
}

defineExpose({
  getValue,
  setValue,
})

</script>
<style>
.editor-container {
  border: 1px solid #ccc;
}
</style>